package bll;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.lang.IllegalArgumentException;
import java.lang.NullPointerException;

public class AnalyseProxy<E> implements Set<E> 
{
	private Set<E> context;
	
	@SuppressWarnings("unused")
	private AnalyseProxy()
	{
		// just for the sake of preventing external initialization
	}
	public AnalyseProxy( Set<E> set )
	{
		this.context = set;
	}
	protected Set<E> getContext()
	{
		if( this.context == null )
		{
			throw new NullPointerException( "Context was not set. Please use the proper Constructor");
		}
		
		return this.context;
	}
	public void setContext( Set<E> set )
	{
		if( this.context != null )
		{
			throw new IllegalArgumentException( "Context was set before. Changing the context on the fly is not supported.");
		}
		this.log( "Context was set");
	}
	@Override
	public boolean add(E e) 
	{
		boolean result = false;
		Logger.Item item;
		
		item = this.trace( "add");
		
		result = this.getContext().add( e );
		
		item.stop();
		
		return result;
	}
	@Override
	public boolean addAll(Collection<? extends E> c) 
	{
		boolean result = false;
		Logger.Item item;
		
		item = this.trace( "addAll" );
		
		result = this.getContext().addAll( c );
		
		item.stop();
		
		return result;
	}
	@Override
	public void clear() 
	{
		this.getContext().clear();
	}
	@Override
	public boolean contains(Object o) 
	{
		boolean result = false;
		Logger.Item item;
		
		item = this.trace( "contains" );
		
		result = this.getContext().contains( o );
		
		item.stop();
		
		return result;
	}
	@Override
	public boolean containsAll(Collection<?> c) 
	{
		boolean result = false;
		Logger.Item item;
		
		item = this.trace( "containsAll" );
		
		result = this.getContext().containsAll( c );
		
		item.stop();
		return result;
	}
	@Override
	public boolean isEmpty() 
	{
		boolean result = false;
		Logger.Item item;
		
		item = this.trace( "isEmpty()" );
		
		result = this.getContext().isEmpty();
		item.stop();
		
		return result;
	}
	@Override
	public Iterator<E> iterator() 
	{
		Iterator<E> result = null;
		Logger.Item item;
		
		item = this.trace( "iterator()");
		
		result = this.getContext().iterator();
		
		item.stop();
		
		return result;
		
	}
	@Override
	public boolean remove(Object o) 
	{
		Logger.Item item;
		boolean result = false;
		
		item = this.trace("remove");
		
		result = this.getContext().remove( o );
		
		item.stop();
		
		return result;
	}

	@Override
	public boolean removeAll(Collection<?> c) 
	{
		Logger.Item item;
		boolean result = false;
		
		item = this.trace( "removeAll" );
		result = this.getContext().removeAll( c );
		item.stop();
		return result;
	}

	@Override
	public boolean retainAll(Collection<?> c) 
	{
		Logger.Item item;
		boolean result = false;
		
		item = this.trace( "retainAll" );
		result = this.getContext().retainAll( c );
		item.stop();
		return result;
	}

	@Override
	public int size() 
	{
		Logger.Item item;
		int size = 0;
		
		item = this.trace( "size()");
		size = this.getContext().size();
		item.stop();
		
		return size;
	}
	@Override
	public Object[] toArray() 
	{
		Logger.Item item;
		Object [] result;
		
		item = this.trace("toArray");
		result = this.getContext().toArray();
		item.stop();
		
		return result;
	}

	@Override
	public <T> T[] toArray(T[] list ) 
	{
		Logger.Item item;
		T [] result;
		
		item = this.trace( "toArray(T[])" );
		result = this.getContext().toArray( list );
		item.stop();
		
		return result;
		
	}
	private void log( String msg )
	{
		Logger.getInstance().debug( msg );
	}
	private Logger.Item trace( String operation )
	{
		Logger.Item item;
		
		item = Logger.getInstance().trace( this.getContext(), operation );
		
		return item;
	}

}